# -*- coding: utf-8 -*-
# @Time: 2021/9/26 15:10
# @Author: yh
# @Remark: 设备状态Server层
import logging
import os
import time

from mxsoftpy import Server
from mxsoftpy.exception import DataError

from db.common.VideoManage.VideoQuality.conf import TestItemsDB, VideoDeviceDB
from db.common.VideoManage.VideoQuality.video import VideoDB
from db.common.VideoManage.VideoQuality.video_state import VideoStateDB
from model.common.VideoManage.VideoQuality.video_state import VideoStateSelectModel
from utils.conf.mxconfig import MxConfig
from utils.public.export_execl import ExportExecl

from utils.public.params_method import update_select_params, get_pagination_params, paging_data


class VideoStateServer(Server):
    __db__ = VideoStateDB

    def __init__(self):
        super().__init__()
        self.__plan_cache = dict()  # 巡检计划详情缓存
        self.__task_cache = dict()  # 巡检任务详情缓存
        self.__video_cache = dict()  # 视频详情缓存
        self.__device_type: dict = VideoDeviceDB('DeviceType').use_keys([])  # 所有设备类型字典

    def _export_data(self, data, headline_dict):
        """
        转换成导出excl所需格式
        param: data 需要转换的列表
        param：test_name_dict 拼接headline
        """

        data_dict = {
            "header": "设备状态",
            "headline": {
                "id": "序号",
                "device_name": "设备名称",
                "device_ip": "网络地址",
                **headline_dict,
            },
            "data": data
        }
        file_name = "state_" + str(int(time.time())) + ".xlsx"
        return data_dict, file_name

    def __select_video_from_cache(self, video_code: str) -> dict:
        """
        从缓存获取视频详情（没有缓存就从数据库获取）
        :param video_code: 要获取的视频code
        """
        if self.__video_cache.get(video_code):
            return self.__video_cache[video_code]
        else:
            self.__video_cache[video_code] = VideoDB().retrieve(video_code)
            return self.__video_cache[video_code]

    def select(self, **select_query) -> dict:
        """
        查询设备状态
        :param select_query: 查询及分页参数，查询参数字段见InspectionRecordSelectModel类
        """
        export_code = select_query.get('export_code')
        select_data = VideoStateSelectModel(**select_query)
        video_query = {
            'name__like': '*%s*' % select_data.device_name,
            'device_ip__like': '*%s*' % select_data.device_ip
        }
        videos = VideoDB().simple_list(**update_select_params(video_query))

        test_items_dict = TestItemsDB('TestItems').use_keys(['name'])  # 所有检查项目
        test_list = []
        headline_dict = {}
        for k, v in test_items_dict.items():
            test_list.append({'test_code': k, 'test_state': v.get(k) or 0, 'test_name': v.get('name')})
            headline_dict[v['name']] = v['name']
        res_list = list()

        i = 0  # 序号
        for code, value in videos.items():
            err_test_list = value['running_error'].split(';')  # video中错误的检测项
            normal_test_list = value['running_normal'].split(';')  # video中正常的检测项
            fail_test_list = value['running_fail'].split(';')  # video中失败的检测项

            video_state_flag_list = ['']  # 本次video状态标志
            if err_test_list == [''] and  fail_test_list == ['']:
                video_state_flag_list.append('1')
            else:
                if err_test_list != ['']:
                    video_state_flag_list.append('3')
                if fail_test_list != ['']:
                    video_state_flag_list.append('2')

            test_data = []  # 本次video中的检测项目状态
            for test_code, test_items in test_items_dict.items():
                if test_code in err_test_list:
                    test_data.append({'name': test_items['name'], 'test_state': 3})
                elif test_code in normal_test_list:
                    test_data.append({'name': test_items['name'], 'test_state': 1})
                elif test_code in fail_test_list:
                    test_data.append({'name': test_items['name'], 'test_state': 2})
                else:
                    test_data.append({'name': test_items['name'], 'test_state': 0})

            i += 1
            res_dict = {
                'id': i,
                'video_code': code,
                'device_name': value['name'],
                'device_ip': value['device_ip'],
                'repair_state': value['repair_state'],
                'vendor': value['vendor'],
                'device_type_code': value['device_type_code'],
                'device_type_name': self.__device_type.get(value['device_type_code'])['name'],
                'test_data': test_data,
                'repair_personnel': value['repair_personnel'],
                'repair_time': time.strftime("%Y-%m-%d %H:%M",
                                             time.localtime(value['repair_time']))}
            if export_code == "1":
                for test_dict in test_data:
                    state_dict = {0: "未检测", 1: "正常", 2: "检测失败", 3: "故障"}
                    res_dict[test_dict['name']] = state_dict.get(test_dict['test_state']) or state_dict.get(0)

            # 筛选符合查询事件类型的数据
            if select_data.test_state.value in video_state_flag_list and (
                    select_data.test_code == '' or
                    select_data.test_code in err_test_list):
                res_list.append(res_dict)

        if export_code == "1":
            data_dict, file_name = self._export_data(res_list, headline_dict)
            path = MxConfig.TMP_DIR + file_name
            execl_path = os.sep + "tmp" + os.sep + file_name

            if data_dict['data']:
                try:
                    ExportExecl().data_process(data_dict)(path)
                    return {'execl_path': execl_path}
                except:
                    logging.error("导出excle出错")
                    raise DataError("导出excle出错")
            else:
                raise DataError("数据为空")

        return paging_data(res_list, **get_pagination_params(select_query))
